package Socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class Server {
    private ServerSocket serverSocket;

    private Map<String,PrintWriter> allOut=new HashMap<>();

    public Server(){
        try {
            System.out.println("服务器正在启动");
            serverSocket=new ServerSocket(8080);
            System.out.println("服务器启动成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start(){
        try {
            while (true){
                System.out.println("等待客户端连接...");
                Socket socket=serverSocket.accept();
                System.out.println("一个客户端连接成功");

                Runnable clientGandler=new ClientGandler(socket);
                Thread thread=new Thread(clientGandler);
                thread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Server server=new Server();

        server.start();
    }
    public class ClientGandler implements Runnable{
        private Socket socket;
        private String host;
        private String nickname;
        public ClientGandler(Socket socket){
            this.socket=socket;
            host=socket.getInetAddress().getHostAddress();
        }
        public void run(){
            PrintWriter pw=null;
            try {
                InputStream is=socket.getInputStream();
                InputStreamReader isr=new InputStreamReader(is, StandardCharsets.UTF_8);
                BufferedReader br=new BufferedReader(isr);

                nickname=br.readLine();

                OutputStream os=socket.getOutputStream();
                OutputStreamWriter osw=new OutputStreamWriter(os, StandardCharsets.UTF_8);
                BufferedWriter bw=new BufferedWriter(osw);
                pw=new PrintWriter(bw,true);
                synchronized (allOut) {
                    allOut.put(nickname, pw);
                }
                broadcast(nickname+"["+host+"]上线了,当前在线人数:"+allOut.size());

                String message;
                while ((message=br.readLine())!=null){
                    if (message.startsWith("@")) {
                        sendMessageToSomeone(message);
                    }else {
                        broadcast(nickname+"["+host+"]说:"+message);
                    }

                }
            } catch (IOException e) {
            } finally {
                synchronized (allOut) {
                    allOut.remove(nickname);
                }
                broadcast(nickname+"["+host+"]下线了,当前在线人数:"+allOut.size());
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        public void broadcast(String message){
            System.out.println(message);
            synchronized (allOut) {
                for (PrintWriter o : allOut.values()) {
                    o.println(message);
                }
            }
        }
        public void sendMessageToSomeone(String message){
            if (message.matches("@.+:.+")) {
                    String toNickName=message.substring(1,message.indexOf(":"));
                if (allOut.containsKey(toNickName)) {
                    PrintWriter pw=allOut.get(toNickName);
                    String toMessage=message.substring(message.indexOf(":")+1);
                    pw.println(nickname+"悄悄对你说:"+toMessage);
                } else {
                    PrintWriter pw=allOut.get(nickname);
                    pw.println("找不到这个人");
                }
            } else {
                PrintWriter pw=allOut.get(nickname);
                pw.println("私聊格式不对,格式应当是@对方名字:内容");
            }
        }
    }
}
